package com.xnyzc.lhy.resource.util;

import com.alibaba.fastjson.JSON;
import com.xnyzc.lhy.common.exception.DiDiException;
import com.xnyzc.lhy.common.penum.EDiDiErrorCode;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.resource.entity.amap.AmapGouldFalcon;
import com.xnyzc.lhy.resource.entity.amap.AmapGpsIdParam;
import com.xnyzc.lhy.resource.entity.amap.AmapTidParam;
import com.xnyzc.lhy.resource.entity.amap.ReGeo;
import com.xnyzc.lhy.resource.entity.amap.ReGeoChild;
import com.xnyzc.lhy.resource.entity.amap.ReGeoChildB;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @Author: huxuekuo
 * @Date: 2019-09-11 14:29
 * @Description: 猎鹰服务
 */
@Slf4j
@Component
public class FalconServiceUtil {

    private static final String GET_GEOCADE_HOST = "https://restapi.amap.com";

    private static final String GET_GEOCADE_PATH = "/v3/geocode/regeo";

    /**
     * 添加服务ID路径
     */
    private static final String ADD_SERVICE_ID_URL = "https://tsapi.amap.com/v1/track/service/add";

    /**
     * 添加猎鹰服务终端ID(每个司机一个终端ID)
     */
    private static final String ADD_TERMINAL_ID_URL = "https://tsapi.amap.com/v1/track/terminal/add";

    /**
     * 删除猎鹰服务终端ID(删除司机时删除终点ID)
     */
    private static final String DELETE_TERMINAL_ID_URL = "https://tsapi.amap.com/v1/track/terminal/delete";

    /**
     * 添加猎鹰服务轨迹ID(每条订单一个)
     */
    private static final String ADD_GPS_ID_URL = "https://tsapi.amap.com/v1/track/trace/add";

    /**
     * 高德 Web API
     */
    public static String webKey;

    @Value("${global.amap.webKey}")
    public void setWebKey(String amapWebKey) {
        webKey = amapWebKey;
    }

    /**
     * 高德返回成功code码
     */
    private static final Integer SUCCESS_CODE = 10000;

    /**
     * 传入几对经纬度返回几段地址
     *
     * @param location
     * @return
     */
    public static String getRegeo(String location) {
        if (CheckUtil.strIsEmpty(location)) {
            throw DiDiException.create(EDiDiErrorCode.parameterError);
        }
        StringBuffer result = new StringBuffer();
        Map<String, String> params = new HashMap<>(6);
        Map<String, String> headers = new HashMap<>(2);
        params.put("key", webKey);
        params.put("location", location);
        params.put("batch", "true");
        try {
            HttpResponse response = HttpUtils.doGet(GET_GEOCADE_HOST, GET_GEOCADE_PATH, "GET", headers, params);
            ReGeo reGeo = JSON.parseObject(EntityUtils.toString(response.getEntity()), ReGeo.class);
            List<ReGeoChild> regeocodes = reGeo.getRegeocodes();
            String address;
            for (ReGeoChild reGeoChild : regeocodes) {
                String buildName = reGeoChild.getAddressComponent().getBuilding().getName();
                address = buildName;
                if (CheckUtil.strIsEmpty(buildName) || StringUtils.equals("[]", buildName)) {
                    String neighName = reGeoChild.getAddressComponent().getNeighborhood().getName();
                    address = neighName;
                    if (CheckUtil.strIsEmpty(neighName) || StringUtils.equals("[]", neighName)) {
                        List<ReGeoChildB> pois = reGeoChild.getPois();
                        if (CheckUtil.collectionIsNotEmpty(pois)) {
                            address = pois.get(0).getName();
                        } else {
                            address = reGeoChild.getFormatted_address();
                        }
                    }
                }
                if (CheckUtil.strIsEmpty(address)) {
                    address = "";
                }
                result.append(address);
                result.append(":");
            }
            result.deleteCharAt(result.length() - 1);
        } catch (Exception e) {
            throw DiDiException.create(EDiDiErrorCode.gaoDeServiceFail);
        }
        return result.toString();
    }

    /**
     * 添加轨迹Id
     *
     * @return
     */
    public static Long addGpsId(AmapGpsIdParam param) {
        Long trId = 0L;
        Map<String, String> params = new HashMap<>();
        try {
            params.put("key", webKey);
            params.put("sid", param.getSid());
            params.put("tid", param.getTid());
            String post = post(ADD_GPS_ID_URL, params);
            AmapGouldFalcon.DataBean dataBean = verificationGetDataBean(post);
            if (CheckUtil.objIsNotEmpty(dataBean)) {
                trId = dataBean.getTrid();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return trId;
    }

    public static void main(String[] args) {
        Long aLong = addGpsId("84017", "225490196");
        System.out.println(aLong);
    }

    /**
     * 添加轨迹Id
     *
     * @return
     */
    public static Long addGpsId(String sid, String tid) {
        Long trId = 0L;
        Map<String, String> params = new HashMap<>();
        try {
            params.put("key", "4815225edd855ffce09b96ec79b96f30");
            params.put("sid", sid);
            params.put("tid", tid);
            String post = post(ADD_GPS_ID_URL, params);
            AmapGouldFalcon.DataBean dataBean = verificationGetDataBean(post);
            if (CheckUtil.objIsNotEmpty(dataBean)) {
                trId = dataBean.getTrid();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return trId;
    }

    /**
     * 添加终端ID
     *
     * @param param
     * @return
     */
    public static Long addTerminalId(AmapTidParam param) {
        Long terminalId = 0L;
        Map<String, String> params = new HashMap<>();
        try {
            params.put("key", webKey);
            params.put("sid", param.getServiceId());
            params.put("name", param.getClientId() + param.getUserId() + param.getTag());
            String post = post(ADD_TERMINAL_ID_URL, params);
            AmapGouldFalcon.DataBean dataBean = verificationGetDataBean(post);
            if (CheckUtil.objIsNotEmpty(dataBean)) {
                terminalId = dataBean.getTid();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return terminalId;
    }

    //
    public static boolean deleteTerminalId(Long sid, Long tid) {
        Map<String, String> param = new HashMap<>();
        param.put("key", webKey);
        param.put("sid", sid.toString());
        param.put("tid", tid.toString());
        try {
            String post = post(DELETE_TERMINAL_ID_URL, param);
            AmapGouldFalcon amapGouldFalcon = verificationGetGouldFalcon(post);
            if (CheckUtil.objIsNotEmpty(amapGouldFalcon)) {
                int errcode = amapGouldFalcon.getErrcode();
                if (SUCCESS_CODE.equals(errcode)) {
                    return true;
                } else {
                    log.error(amapGouldFalcon.getErrmsg());
                    return false;
                }
            }
        } catch (IOException e) {
            log.error("猎鹰服务删除终端ID失败");
            log.error(e.getMessage());
        }
        return false;
    }

    /**
     * 检验数据返回消息类
     *
     * @param json
     * @return
     */
    public static AmapGouldFalcon verificationGetGouldFalcon(String json) {
        AmapGouldFalcon amapGouldFalcon = JSON.parseObject(json, AmapGouldFalcon.class);
        if (CheckUtil.objIsEmpty(amapGouldFalcon)) {
            log.info("猎鹰返回数据为空!");
            return null;
        }
        return amapGouldFalcon;
    }

    /**
     * 检验数据返回数据类型
     *
     * @param json
     * @return
     */
    public static AmapGouldFalcon.DataBean verificationGetDataBean(String json) {
        AmapGouldFalcon amapGouldFalcon = JSON.parseObject(json, AmapGouldFalcon.class);
        if (CheckUtil.objIsEmpty(amapGouldFalcon)) {
            log.info("猎鹰返回数据为空!");
            return null;
        }
        AmapGouldFalcon.DataBean data = amapGouldFalcon.getData();
        if (CheckUtil.objIsEmpty(data)) {
            log.info("猎鹰返回数据data为空!");
            return null;
        }
        return data;
    }

    /**
     * 添加猎鹰服务ID
     *
     * @param name
     * @param desc
     * @return
     */
    public static Long addServiceId(String name, String desc) {
        Map<String, String> param = new HashMap<>();
        Long sid = 0L;
        try {
            param.put("key", webKey);
            param.put("name", name);
            param.put("desc", desc);
            String post = post(ADD_SERVICE_ID_URL, param);
            AmapGouldFalcon.DataBean dataBean = verificationGetDataBean(post);
            if (CheckUtil.objIsNotEmpty(dataBean)) {
                sid = dataBean.getSid();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sid;
    }


    /**
     * 封装HTTP POST方法
     *
     * @param
     * @param
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String post(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException {
        HttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        // 设置请求和传输超时时间
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
        httpPost.setConfig(requestConfig);
        httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
        List<NameValuePair> formparams = setHttpParams(paramMap);
        UrlEncodedFormEntity param = new UrlEncodedFormEntity(formparams, "UTF-8");
        httpPost.setEntity(param);
        HttpResponse response = httpClient.execute(httpPost);
        log.info("************{}" + response);
        String httpEntityContent = getHttpEntityContent(response);
        log.info("************{}" + httpEntityContent);
        httpPost.abort();
        log.info("************{}" + httpEntityContent);
        return httpEntityContent;

    }

    /**
     * 设置请求参数
     *
     * @param
     * @return
     */
    private static List<NameValuePair> setHttpParams(Map<String, String> paramMap) {
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        Set<Map.Entry<String, String>> set = paramMap.entrySet();
        for (Map.Entry<String, String> entry : set) {
            formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        return formparams;
    }

    /**
     * 获得响应HTTP实体内容
     *
     * @param response
     * @return
     * @throws IOException
     * @throws UnsupportedEncodingException
     */
    private static String getHttpEntityContent(HttpResponse response) throws IOException, UnsupportedEncodingException {
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream is = entity.getContent();
            BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String line = br.readLine();
            StringBuilder sb = new StringBuilder();
            while (line != null) {
                sb.append(line + "\n");
                line = br.readLine();
            }
            return sb.toString();
        }
        return "";
    }

    public static Long addTerminalId(String serviceId, Long userId, String clientId, String tag) {
        Long terminalId = 0L;
        log.info("serviceID: "+serviceId+" ,userId: "+userId);
        Map<String, String> params = new HashMap<>();
        try {
            params.put("key", webKey);
            params.put("sid", serviceId);
            params.put("name", userId + "" + clientId + "" + tag);
            String post = post(ADD_TERMINAL_ID_URL, params);
            AmapGouldFalcon.DataBean dataBean = verificationGetDataBean(post);
            if (CheckUtil.objIsNotEmpty(dataBean)) {
                terminalId = dataBean.getTid();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.info("return : "+terminalId);
        return terminalId;
    }
}
